@namespace Oqtane.Modules.Admin.Logs
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject ILogService LogService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer

@if (_logs == null)
{
    <p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
    <TabStrip>
        <TabPanel Name="Events" Heading="Events" ResourceKey="Events">
			<div class="container g-0">
				<div class="row mb-1 align-items-center">
					<div class="col-sm-4">
						<Label For="level" HelpText="Select the log level for event log items" ResourceKey="Level">Level: </Label><br /><br />
						<select id="level" class="form-select" value="@_level" @onchange="(e => LevelChanged(e))">
							<option value="-">&lt;@Localizer["AllLevels"]&gt;</option>
							<option value="Trace">@Localizer["Trace"]</option>
							<option value="Debug">@Localizer["Debug"]</option>
							<option value="Information">@Localizer["Information"]</option>
							<option value="Warning">@Localizer["Warning"]</option>
							<option value="Error">@Localizer["Error"]</option>
							<option value="Critical">@Localizer["Critical"]</option>
						</select>
					</div>            
					<div class="col-sm-4">
						<Label For="function" HelpText="Select the function for event log items" ResourceKey="Function">Function: </Label><br /><br />
						<select id="function" class="form-select" value="@_function" @onchange="(e => FunctionChanged(e))">
							<option value="-">&lt;@Localizer["AllFunctions"]&gt;</option>
							<option value="Create">@Localizer["Create"]</option>
							<option value="Read">@Localizer["Read"]</option>
							<option value="Update">@SharedLocalizer["Update"]</option>
							<option value="Delete">@SharedLocalizer["Delete"]</option>
							<option value="Security">@Localizer["Security"]</option>
							<option value="Other">@Localizer["Other"]</option>
						</select>
					</div>            
					<div class="col-sm-4">
						<Label For="rows" HelpText="Select the maximum number of event log items to review. Please note that if you choose more than 10 items the information will be split into pages." ResourceKey="Rows">Maximum Items: </Label><br /><br />
						<select id="rows" class="form-select" value="@_rows" @onchange="(e => RowsChanged(e))">
							<option value="10">10</option>
							<option value="50">50</option>
							<option value="100">100</option>
						</select>
					</div>
				</div>
			</div>
			<br />

			@if (_logs.Any())
			{
				<Pager Items="@_logs" CurrentPage="@_page.ToString()" OnPageChange="OnPageChange">
					<Header>
						<th style="width: 1px;">&nbsp;</th>
						<th>@Localizer["Date"]</th>
						<th>@Localizer["Level"]</th>
						<th>@Localizer["Feature"]</th>
						<th>@Localizer["Function"]</th>
					</Header>
					<Row>
                        <td class="@GetClass(context.Function)"><ActionLink Action="Detail" Text="Details" Parameters="@($"/{context.LogId}")" ReturnUrl="@(NavigateUrl(PageState.Page.Path, AddUrlParameters(_level, _function, _rows, _page)))" ResourceKey="LogDetails" /></td>
						<td class="@GetClass(context.Function)">@UtcToLocal(context.LogDate)</td>
						<td class="@GetClass(context.Function)">@context.Level</td>
						<td class="@GetClass(context.Function)">@context.Feature</td>
						<td class="@GetClass(context.Function)">@context.Function</td>
					</Row>
				</Pager>
			}
			else
			{
				<p><em>@Localizer["NoLogs"]</em></p>
			}
		</TabPanel>
        <TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
			<div class="container">
				<div class="row mb-1 align-items-center">
					<Label Class="col-sm-3" For="retention" HelpText="Number of days of events to retain" ResourceKey="Retention">Retention (Days): </Label>
					<div class="col-sm-9">
                        <input id="retention" type="number" min="0" step="1" class="form-control" @bind="@_retention" />
					</div>
				</div>
			</div>
			<br />
            <button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
            <ActionDialog Header="Clear Events" Message="Are You Sure You Wish To Remove All Log Events?" Action="DeleteLogs" Class="btn btn-danger" OnClick="@(async () => await DeleteLogs())" ResourceKey="DeleteLogs" />
		</TabPanel>
	</TabStrip>
}

@code {
    private string _level = "-";
    private string _function = "-";
    private string _rows = "10";
    private int _page = 1;
    private List<Log> _logs;
    private int _retention = 30;

    public override string UrlParametersTemplate => "/{level}/{function}/{rows}/{page}";
    public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;

    protected override async Task OnParametersSetAsync()
    {
        try
        {
            if (UrlParameters.ContainsKey("level"))
            {
                _level = UrlParameters["level"];
            }
            if (UrlParameters.ContainsKey("function"))
            {
                _function = UrlParameters["function"];
            }
            if (UrlParameters.ContainsKey("rows"))
            {
                _rows = UrlParameters["rows"];
            }
            if (UrlParameters.ContainsKey("page") && int.TryParse(UrlParameters["page"], out int page))
            {
                _page = page;
            }

            await GetLogs();

            var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
            _retention = int.Parse( SettingService.GetSetting(settings, "LogRetention", "30"));
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
        }
    }

    private async void LevelChanged(ChangeEventArgs e)
    {
        try
        {
            _level = (string)e.Value;
            await GetLogs();
            StateHasChanged();
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
        }
    }

    private async void FunctionChanged(ChangeEventArgs e)
    {
        try
        {
            _function = (string)e.Value;
            await GetLogs();
            StateHasChanged();
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
        }
    }


    private async void RowsChanged(ChangeEventArgs e)
    {
        try
        {
            _rows = (string)e.Value;
            await GetLogs();
            StateHasChanged();
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
        }
    }

    private async Task GetLogs()
    {
        _logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((_level == "-") ? string.Empty : _level), ((_function == "-") ? string.Empty : _function), int.Parse(_rows));
    }

    private string GetClass(string function)
    {
        string classname = string.Empty;
        switch (function)
        {
            case "Create":
                classname = "table-success";
                break;
            case "Read":
                classname = "table-primary";
                break;
            case "Update":
                classname = "table-warning";
                break;
            case "Delete":
                classname = "table-danger";
                break;
            case "Security":
                classname = "table-secondary";
                break;
            default:
                classname = string.Empty;
                break;
        }
        return classname;
    }

    private async Task SaveSiteSettings()
    {
        try
        {
            var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
            settings = SettingService.SetSetting(settings, "LogRetention", _retention.ToString(), true);
            await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);

            AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success);
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Saving Site Settings {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error);
        }
    }

    private async Task DeleteLogs()
    {
        try
        {
            await LogService.DeleteLogsAsync(PageState.Site.SiteId);
            await GetLogs();
            StateHasChanged();
        }
        catch (Exception ex)
        {
            await logger.LogError(ex, "Error Deleting Logs {Error}", ex.Message);
            AddModuleMessage(Localizer["Error.DeleteLogs"], MessageType.Error);
        }
    }

	private void OnPageChange(int page)
	{
		_page = page;	
	}

	protected override void OnAfterRender(bool firstRender)
	{
		if (firstRender)
		{
			// external link to log item will display Details component
			if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id))
			{
				NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}"));
			}
		}
	}
}
